home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / jctrl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-04  |  23.4 KB  |  959 lines

  1. /* 
  2.  * jctrl.c --
  3.  *
  4.  *    Perform sysadmin duties on Jaquith robot.
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "We would like to apologize for the way in which politicians are
  17.  *      represented in this programme.  It was never our intention to imply
  18.  *      that politicians are weak-kneed, political time-servers who are more
  19.  *      concerned with their personal vendettas and private power struggles
  20.  *      than the problems of government, nor to suggest at any point that
  21.  *      they sacrifice their credibility by denying free debate on vital
  22.  *      matters in the mistaken impression that party unity comes before
  23.  *      the well-being of the people they supposedly represent, nor to imply
  24.  *      at any stage that they are squabbling little toadies without an ounce
  25.  *      of concern for the vital social problems of today.  Nor indeed do we
  26.  *      intend that viewers should consider them as crabby ulcerous little
  27.  *      self-seeking vermin with furry legs and an excessive addiction to
  28.  *      alcohol and certain explicit sexual practices which some people might
  29.  *      find offensive.  We are sorry if this impression has come across."
  30.  *      -- Monty Python
  31.  */
  32.  
  33. #ifndef lint
  34. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/jquery.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  35. #endif /* not lint */
  36.  
  37. #include "jaquith.h"
  38. #include "option.h"
  39.  
  40. static char printBuf[T_MAXSTRINGLEN];
  41.  
  42. static FILE *memDbg = NULL;   /* stream for memory tracing */
  43.  
  44. int jDebug;                   /* Internal debugging only */
  45. int syserr = 0;               /* Our personal record of errno */
  46.  
  47. #define DEF_VOL -1
  48. #define DEF_SLOT -1
  49. #define DEF_SLOT2 -1
  50. #define DEF_DEV ""
  51. #define DEF_VERBOSE 0
  52. #define DEF_CMD ""
  53. #define DEF_MSG ""
  54.  
  55. #define NUMCMDS 9
  56. #define CMD_INSERT    0x01
  57. #define CMD_REMOVE    0x02
  58. #define CMD_LOAD      0x03
  59. #define CMD_UNLOAD    0x04
  60. #define CMD_OPENDOOR  0x05
  61. #define CMD_DISPMSG   0x06
  62. #define CMD_MOVE      0x07
  63. #define CMD_READLABEL 0x08
  64. #define CMD_LISTVOLS  0x09
  65.  
  66. #define NEEDVOL   0x01
  67. #define NEEDSLOT  0x02
  68. #define NEEDSLOT2 0x04
  69. #define NEEDDEV   0x08
  70.  
  71. typedef struct cmd {
  72.     char *name;               /* cmd name */
  73.     int id;                   /* cmd identifier */
  74.     int flags;                /* cmd's required args */
  75. } Cmd;
  76.  
  77. static void  CheckOptions     _ARGS_ ((Parms *parmsPtr, int *cmdPtr));
  78. static void  InsertVolume     _ARGS_ ((int volId, int slot));
  79. static void  RemoveVolume     _ARGS_ ((int volId));
  80. static void  LoadVolume       _ARGS_ ((int volId, char *dev));
  81. static void  UnloadVolume     _ARGS_ ((int volId, char *dev));
  82. static void  MoveVolume       _ARGS_ ((int srcSlot, int destSlot));
  83. static void  ReadVolLabel     _ARGS_ ((int srcSlot));
  84. static void  OpenDoor         _ARGS_ (());
  85. static void  BuildVolList     _ARGS_ (());
  86. static Cmd  *FindCmdInList    _ARGS_ ((char *cmd));
  87. static int   FindVolumeInList _ARGS_ ((int volId));
  88. static int   FindDeviceInList _ARGS_ ((char *reader));
  89. static int   FindSlotInList   _ARGS_ ((int slot));
  90. static int   PruneDirectory   _ARGS_ ((int minTBuf,int maxTBuf,
  91.                        char *dirPath, char *curPath));
  92.  
  93. static int robotStream = -1;
  94. static DevConfig *devList = NULL;
  95. static VolConfig *volList= NULL;
  96. static int devCnt = 0;
  97. static int volCnt = 0;
  98.  
  99. typedef struct parmTag {
  100.     char *cmd;
  101.     int volId;
  102.     int slot;
  103.     int slot2;
  104.     char *dev;
  105.     char *root;
  106.     int verbose;
  107.     char *robot;
  108.     char *devFile;
  109.     char *volFile;
  110.     char *msg;
  111. } Parms;
  112.  
  113. Parms parms = {
  114.     DEF_CMD,
  115.     DEF_VOL,
  116.     DEF_SLOT,
  117.     DEF_SLOT2,
  118.     DEF_DEV,
  119.     DEF_ROOT,
  120.     DEF_VERBOSE,
  121.     DEF_ROBOT,
  122.     DEF_DEVFILE,
  123.     DEF_VOLFILE,
  124.     DEF_MSG
  125. };
  126.  
  127. Option optionArray[] = {
  128.     {OPT_STRING, "cmd", (char *)&parms.cmd, "Main command option"},
  129.     {OPT_INT, "vol", (char *)&parms.volId, "Volume id. Required."},
  130.     {OPT_INT, "slot", (char *)&parms.slot, "Volume's home location."},
  131.     {OPT_INT, "slot2", (char *)&parms.slot2, "Destination for move cmd."},
  132.     {OPT_STRING, "dev", (char *)&parms.dev, "Device name."},
  133.     {OPT_STRING, "root", (char *)&parms.root, "root of index tree"},
  134.     {OPT_TRUE, "v", (char *)&parms.verbose, "Verbose mode"},
  135.  
  136.     {OPT_STRING, "robot", (char *)&parms.robot, "Robot device name"},
  137.     {OPT_STRING, "devfile", (char *)&parms.devFile, "Device config file"},
  138.     {OPT_STRING, "volfile", (char *)&parms.volFile, "Volume config file"},
  139.     {OPT_STRING, "msg", (char *)&parms.msg, "Display message on jukebox"}
  140. };
  141. int numOptions = sizeof(optionArray) / sizeof(Option);
  142.  
  143.  
  144. /*
  145.  *----------------------------------------------------------------------
  146.  *
  147.  * jctrl --
  148.  *
  149.  *    Main driver for manual jukebox manipulations
  150.  *
  151.  * Results:
  152.  *    none.
  153.  *
  154.  * Side effects:
  155.  *    none.
  156.  *
  157.  *----------------------------------------------------------------------
  158.  */
  159.  
  160. int
  161. main(argc, argv)
  162.     int argc;                 /* See Option Array */
  163.     char *argv[];
  164. {
  165.     int retCode;
  166.     int cmd;
  167.  
  168. /*    memDbg = fopen("jctrl.mem","w"); */
  169.     MEM_CONTROL(8192, memDbg, TRACEMEM+TRACECALLS, 4096);
  170.  
  171.     argc = Opt_Parse(argc, argv, optionArray, numOptions, 0);
  172.  
  173.     CheckOptions(&parms, &cmd);
  174.  
  175.     if ((cmd != CMD_OPENDOOR) &&
  176.     (cmd != CMD_DISPMSG) &&
  177.     (cmd != CMD_LISTVOLS)) {
  178.     /* Obtain list of known volumes */
  179.     Admin_ReadVolConfig(parms.volFile, NULL, &volCnt);
  180.     volList = (VolConfig *)MEM_ALLOC("main",volCnt*sizeof(VolConfig));
  181.     if (Admin_ReadVolConfig(parms.volFile, volList, &volCnt) != T_SUCCESS) {
  182.         sprintf(printBuf,"Can't read %s: %s\nContinue? [y/n] ",
  183.             parms.volFile, sys_errlist[syserr]);
  184.         if (!Utils_GetOk(printBuf)) {
  185.         exit(-1);
  186.         }
  187.     }
  188.  
  189.     /* Obtain list of known devices */    
  190.     Admin_ReadDevConfig(parms.devFile, NULL, &devCnt);
  191.     devList = (DevConfig *)MEM_ALLOC("main",devCnt*sizeof(DevConfig));
  192.     if (Admin_ReadDevConfig(parms.devFile, devList, &devCnt) != T_SUCCESS) {
  193.         sprintf(printBuf,"Can't read %s: %s\nContinue? [y/n] ", 
  194.             parms.devFile, sys_errlist[syserr]);
  195.         if (!Utils_GetOk(printBuf)) {
  196.         exit(-1);
  197.         }
  198.     }
  199.     }
  200.  
  201.     /* Open robot */
  202.     if (Dev_InitRobot(parms.robot, &robotStream) != T_SUCCESS) {
  203.     sprintf(printBuf,"Couldn't open robot: %s\n", sys_errlist[syserr]);
  204.     Utils_Bailout(printBuf, BAIL_PRINT);
  205.     }
  206.  
  207.     switch (cmd) {
  208.     case CMD_INSERT:
  209.     InsertVolume(parms.volId, parms.slot);
  210.     break;
  211.     case CMD_REMOVE:
  212.     RemoveVolume(parms.volId);
  213.     break;
  214.     case CMD_LOAD:
  215.     LoadVolume(parms.volId, parms.dev);
  216.     break;
  217.     case CMD_UNLOAD:
  218.     UnloadVolume(parms.volId, parms.dev);
  219.     break;
  220.     case CMD_OPENDOOR:
  221.     OpenDoor();
  222.     break;
  223.     case CMD_MOVE:
  224.     MoveVolume(parms.slot, parms.slot2);
  225.     break;
  226.     case CMD_READLABEL:
  227.     ReadVolLabel(parms.slot);
  228.     break;
  229.     case CMD_LISTVOLS:
  230.     BuildVolList();
  231.     break;
  232.     case CMD_DISPMSG:
  233.     Dev_DisplayMsg(robotStream, parms.msg, 0);
  234.     break;
  235.     default:
  236.     fprintf(stderr,"!! unexpected command: %d\n", cmd);
  237.     }
  238.  
  239.     if (robotStream != -1) {
  240.     close(robotStream);
  241.     }
  242.  
  243.     MEM_REPORT("jctrl", ALLROUTINES, SORTBYOWNER);
  244.  
  245.     return 0;
  246. }
  247.  
  248.  
  249.  
  250. /*
  251.  *----------------------------------------------------------------------
  252.  *
  253.  * InsertVolume --
  254.  *
  255.  *    Add a volume to the physical archive.
  256.  *
  257.  * Results:
  258.  *    none.
  259.  *
  260.  * Side effects:
  261.  *    none.
  262.  *
  263.  *----------------------------------------------------------------------
  264.  */
  265. static void
  266. InsertVolume(volId, slot)
  267.     int volId;                /* volume id */
  268.     int slot;                 /* home location */
  269. {
  270.     VolOwner *volOwnerPtr;
  271.  
  272.     if ((volCnt > 0) &&
  273.     ((slot=FindSlotInList(volId)) != -1)) {
  274.     sprintf(printBuf,"Slot already in use by volume %d. Insert [n/y] ",
  275.         volList[slot].volId);
  276.     if (!Utils_GetOk(printBuf)) {
  277.         return;
  278.     }
  279.     
  280.     }
  281.  
  282.     volOwnerPtr = Admin_FindVolOwner(volId, parms.root, "*.arch");
  283.     if (volOwnerPtr->owner != NULL) {
  284.     sprintf(printBuf, "Volume %d already owned by %s. Continue? [y/n] ",
  285.            volId, volOwnerPtr->owner);
  286.     if (!Utils_GetOk(printBuf)) {
  287.         return;
  288.     }
  289.     }
  290.  
  291.     if (Dev_InsertVolume(robotStream, slot) != T_SUCCESS) {
  292.     sprintf(printBuf,"Insertion failed: %s\n", sys_errlist[syserr]);
  293.     Utils_Bailout(printBuf, BAIL_PRINT);
  294.     }
  295.  
  296.     if (Utils_GetOk("Add volume to free list? ")) {
  297.     if (Admin_PutFreeVol(parms.root,volId) != T_SUCCESS) {
  298.         fprintf(stderr,"Couldn't add volume to free list: %s\n",
  299.             sys_errlist[syserr]);
  300.     } else if (parms.verbose) {
  301.         fprintf(stdout,"Volume added to free list.\n");
  302.     }
  303.     }
  304.  
  305.     if (parms.verbose) {
  306.     fprintf(stdout,"Volume %d inserted.\n",    volId);
  307.     }
  308. }
  309.  
  310.  
  311. /*
  312.  *----------------------------------------------------------------------
  313.  *
  314.  * RemoveVolume --
  315.  *
  316.  *    Remove a volume from the physical archive.
  317.  *
  318.  * Results:
  319.  *    none.
  320.  *
  321.  * Side effects:
  322.  *    none.
  323.  *
  324.  *----------------------------------------------------------------------
  325.  */
  326. static void
  327. RemoveVolume(volId)
  328.     int volId;                /* volume Id */
  329. {
  330.     VolOwner *volOwnerPtr;
  331.     int slot;
  332.     int pruneCnt;
  333.     int len;
  334.     char *dirPath;
  335.  
  336.     if ((slot=FindVolumeInList(volId)) == -1) {
  337.     sprintf(printBuf,"What slot is volume %d in? (return to abort) ", volId);
  338.     if ((slot=Utils_GetInteger(printBuf, 0, INT_MAX)) < 0) {
  339.         exit(-1);
  340.     }
  341.     }
  342.  
  343.     if ((volOwnerPtr=Admin_FindVolOwner(volId, parms.root,"*.arch")) == NULL) {
  344.     sprintf(printBuf,"Couldn't read owner information for volume %d.\n",
  345.         volId);
  346.     } else if (volOwnerPtr->owner != NULL) {
  347.     sprintf(printBuf, "Volume %d in use by %s. Remove? [y/n] ",
  348.            volId, volOwnerPtr->owner);
  349.     if (!Utils_GetOk(printBuf)) {
  350.         return;
  351.     }
  352.     } else if (Utils_GetOk("Remove volume from free list? ")) {
  353.     if (Admin_GetFreeVol(parms.root, &volId) != T_SUCCESS) {
  354.         sprintf(printBuf,"Couldn't remove volume from free list. Continue? [y/n] ");
  355.         if (!Utils_GetOk(printBuf)) {
  356.         return;
  357.         }
  358.     } else if (parms.verbose) {
  359.         fprintf(stdout, "Removed volume from free list.\n");
  360.         fflush(stdout);
  361.     }
  362.     }
  363.  
  364.     if     ((volOwnerPtr != NULL) &&
  365.      (volOwnerPtr->owner != NULL) &&
  366.       (Utils_GetOk("Remove all references to volume from index? "))) {
  367.     dirPath = Str_Cat(3, parms.root, "/", volOwnerPtr->owner);
  368.     if ((pruneCnt=PruneDirectory(volOwnerPtr->minTBuf,
  369.                      volOwnerPtr->maxTBuf,
  370.                      dirPath, "")) == -1) {
  371.         sprintf(printBuf,"Couldn't prune index. errno %d", syserr);
  372.     } else if (parms.verbose) {
  373.         fprintf(stdout, "Pruned %d items from index.\n", pruneCnt);
  374.         fflush(stdout);
  375.     }
  376.     }
  377.  
  378.     if (Dev_RemoveVolume(robotStream, slot) != T_SUCCESS) {
  379.     sprintf(printBuf,"Removal failed: %s\n", sys_errlist[syserr]);
  380.     Utils_Bailout(printBuf, BAIL_PRINT);
  381.     }
  382.  
  383.     if (parms.verbose) {
  384.     fprintf(stdout,"Removed volume %d.\n", volId);
  385.     }
  386.     
  387. }
  388.  
  389.  
  390. /*
  391.  *----------------------------------------------------------------------
  392.  *
  393.  * LoadVolume --
  394.  *
  395.  *    Load a volume into a reader
  396.  *
  397.  * Results:
  398.  *    none.
  399.  *
  400.  * Side effects:
  401.  *    none.
  402.  *
  403.  *----------------------------------------------------------------------
  404.  */
  405. static void
  406. LoadVolume(volId, dev)
  407.     int volId;                /* source volume id */
  408.     char *dev;                /* destination device name */
  409. {
  410.     int volSlot;
  411.     int devSlot;
  412.  
  413.     if ((volSlot=FindVolumeInList(volId)) == -1) {
  414.     sprintf(printBuf,"Don't know location of volume %d.\n", volId);
  415.     Utils_Bailout(printBuf, BAIL_PRINT);
  416.     }
  417.  
  418.     if ((devSlot=FindDeviceInList(dev)) == -1) {
  419.     sprintf(printBuf,"Don't know location of device %s.\n", dev);
  420.     Utils_Bailout(printBuf, BAIL_PRINT);
  421.     }
  422.  
  423.     if (Dev_MoveVolume(robotStream, volSlot, devSlot) != T_SUCCESS) {
  424.     sprintf(printBuf,"Couldn't load volume %d into %s: %s\n",
  425.         volId, dev, sys_errlist[syserr]);
  426.     Utils_Bailout(printBuf, BAIL_PRINT);
  427.     }
  428.  
  429.     if (parms.verbose) {
  430.     fprintf(stdout,"Volume %d loaded from slot %d into %s.\n",
  431.         volSlot, volId, dev);
  432.     }
  433.  
  434. }
  435.  
  436.  
  437. /*
  438.  *----------------------------------------------------------------------
  439.  *
  440.  * UnloadVolume --
  441.  *
  442.  *    Unload a volume from a reader
  443.  *
  444.  * Results:
  445.  *    none.
  446.  *
  447.  * Side effects:
  448.  *    none.
  449.  *
  450.  *----------------------------------------------------------------------
  451.  */
  452. static void
  453. UnloadVolume(volId, dev)
  454.     int volId;                /* source volume */
  455.     char *dev;                /* source device name */
  456. {
  457.     int volSlot;
  458.     int devSlot;
  459.  
  460.     if ((volSlot=FindVolumeInList(volId)) == -1) {
  461.     sprintf(printBuf,"Don't know location of volume %d.\n", volId);
  462.     Utils_Bailout(printBuf, BAIL_PRINT);
  463.     }
  464.  
  465.     if ((devSlot=FindDeviceInList(dev)) == -1) {
  466.     sprintf(printBuf,"Don't know location of device %s.\n", dev);
  467.     Utils_Bailout(printBuf, BAIL_PRINT);
  468.     }
  469.  
  470.     if (parms.verbose) {
  471.     fprintf(stdout,"Ejecting volume from device %s...", dev);
  472.     fflush(stdout);
  473.     }
  474.  
  475.     if (Dev_UnloadVolume(dev) != T_SUCCESS) {
  476.     sprintf(printBuf,"Couldn't eject device %s: %s\n",
  477.         dev, sys_errlist[syserr]);
  478.     Utils_Bailout(printBuf, BAIL_PRINT);
  479.     }
  480.  
  481.     if (parms.verbose) {
  482.     fprintf(stdout,"ejected.\n");
  483.     fflush(stdout);
  484.     }
  485.  
  486.     if (Dev_MoveVolume(robotStream, devSlot, volSlot) != T_SUCCESS) {
  487.     sprintf(printBuf,"Couldn't unload volume %d from %s: %s\n",
  488.         volId, dev, sys_errlist[syserr]);
  489.     Utils_Bailout(printBuf, BAIL_PRINT);
  490.     }
  491.  
  492.     if (parms.verbose) {
  493.     fprintf(stdout,"Volume %d unloaded from %s to slot %d.\n",
  494.         volId, dev, volSlot);
  495.     }
  496.  
  497. }
  498.  
  499.  
  500. /*
  501.  *----------------------------------------------------------------------
  502.  *
  503.  * MoveVolume --
  504.  *
  505.  *    Move volume from 1 slot to another
  506.  *
  507.  * Results:
  508.  *    none.
  509.  *
  510.  * Side effects:
  511.  *    none.
  512.  *
  513.  *----------------------------------------------------------------------
  514.  */
  515. static void
  516. MoveVolume(srcSlot, destSlot)
  517.     int srcSlot;              /* source location */
  518.     int destSlot;             /* destination volume */
  519. {
  520.  
  521.     if (Dev_MoveVolume(robotStream, srcSlot, destSlot) != T_SUCCESS) {
  522.     sprintf(printBuf,"Couldn't move volume from %d to %d: %s\n",
  523.         srcSlot, destSlot, sys_errlist[syserr]);
  524.     Utils_Bailout(printBuf, BAIL_PRINT);
  525.     }
  526.  
  527.     if (parms.verbose) {
  528.     fprintf(stdout,"Volume moved from slot %d to slot %d.\n",
  529.         srcSlot, destSlot);
  530.     }
  531.  
  532. }
  533.  
  534.  
  535. /*
  536.  *----------------------------------------------------------------------
  537.  *
  538.  * MoveVolume --
  539.  *
  540.  *    Move volume from 1 slot to another
  541.  *
  542.  * Results:
  543.  *    none.
  544.  *
  545.  * Side effects:
  546.  *    none.
  547.  *
  548.  *----------------------------------------------------------------------
  549.  */
  550. static void
  551. ReadVolLabel(srcSlot)
  552.     int srcSlot;              /* source location */
  553. {
  554.     char volLabel[T_MAXSTRINGLEN];
  555.     int volId;
  556.  
  557.     if (Dev_ReadVolLabel(robotStream, srcSlot, volLabel, &volId)!= T_SUCCESS) {
  558.     fprintf(stderr,"Couldn't read volume label in slot %d: %s\n",
  559.         srcSlot, sys_errlist[syserr]);
  560.     } else {
  561.     fprintf(stdout,"Volume in slot %d has label: %s.\n",
  562.         srcSlot, volLabel);
  563.     }
  564.  
  565. }
  566.  
  567.  
  568.  
  569. /*
  570.  *----------------------------------------------------------------------
  571.  *
  572.  * OpenDoor --
  573.  *
  574.  *    Open door to jukebox.
  575.  *
  576.  * Results:
  577.  *    none.
  578.  *
  579.  * Side effects:
  580.  *    Takes jukebox offline.
  581.  *
  582.  *----------------------------------------------------------------------
  583.  */
  584. static void
  585. OpenDoor()
  586. {
  587.     if (Dev_OpenDoor(robotStream) != T_SUCCESS) {
  588.     fprintf(stderr,"Couldn't open door: %s\n", sys_errlist[syserr]);
  589.     } else if (parms.verbose) {
  590.     fprintf(stdout,"Door released.\n");
  591.     }
  592. }
  593.  
  594.  
  595.  
  596. /*
  597.  *----------------------------------------------------------------------
  598.  *
  599.  * BuildVolList --
  600.  *
  601.  *    Create list of 
  602.  *
  603.  * Results:
  604.  *    none.
  605.  *
  606.  * Side effects:
  607.  *    None.
  608.  *
  609.  *----------------------------------------------------------------------
  610.  */
  611. static void
  612. BuildVolList()
  613. {
  614.     int cnt = 0;
  615.     VolConfig *listPtr;
  616.     VolConfig *workPtr;
  617.  
  618.     Dev_BuildVolList(robotStream, NULL, &cnt);
  619.     listPtr = (VolConfig *)MEM_ALLOC("BuildVolList",cnt*sizeof(VolConfig));
  620.     if (Dev_BuildVolList(robotStream, listPtr, &cnt) != T_SUCCESS) {
  621.     fprintf(stderr,"Couldn't build volume list: %s\n",
  622.         sys_errlist[syserr]);
  623.     MEM_FREE("BuildVolList",listPtr);
  624.     } else {
  625.     workPtr = listPtr;
  626.     while (cnt--) {
  627.         fprintf(stdout, "%d %d %s\n",
  628.             workPtr->volId, workPtr->location, workPtr->volLabel);
  629.         workPtr++;
  630.     }
  631.     MEM_FREE("BuildVolList",listPtr);
  632.     }
  633. }
  634.  
  635.  
  636.  
  637. /*
  638.  *----------------------------------------------------------------------
  639.  *
  640.  * FindVolumeInList --
  641.  *
  642.  *    Locate volumeId in list.
  643.  *
  644.  * Results:
  645.  *    none.
  646.  *
  647.  * Side effects:
  648.  *    none.
  649.  *
  650.  *----------------------------------------------------------------------
  651.  */
  652.  
  653. static int
  654. FindVolumeInList(volId)
  655.     int volId;                /* volume Id */
  656. {
  657.     int i;
  658.  
  659.     /* Must inquire, if we don't have a volconfig file */
  660.     if (volCnt == 0) {
  661.     sprintf(stderr, "What slot is volume %d in? [<return> to exit] ",
  662.         volId);
  663.     return Utils_GetInteger(printBuf, 0, INT_MAX);
  664.     }
  665.  
  666.     for (i=0; i<volCnt; i++) {
  667.     if (volId == volList[i].volId) {
  668.         return volList[i].location;
  669.     }
  670.     }
  671.     return -1;
  672. }
  673.  
  674.  
  675. /*
  676.  *----------------------------------------------------------------------
  677.  *
  678.  * FindSlotInList --
  679.  *
  680.  *    Locate slot in list.
  681.  *
  682.  * Results:
  683.  *    none.
  684.  *
  685.  * Side effects:
  686.  *    none.
  687.  *
  688.  *----------------------------------------------------------------------
  689.  */
  690.  
  691. static int
  692. FindSlotInList(slot)
  693.     int slot;                 /* slot number */
  694. {
  695.     int i;
  696.     char volLabel[T_MAXLABELLEN];
  697.  
  698.     /* Must inquire, if we don't have a volconfig file */
  699.     if (volCnt == 0) {
  700.     if (Dev_ReadVolLabel(robotStream, slot, volLabel, &i) == T_SUCCESS) {
  701.         return i;
  702.     } else {
  703.         sprintf(printBuf, "What volume is in slot %d? [<return> to exit] ",
  704.             slot);
  705.         return Utils_GetInteger(printBuf, 0, INT_MAX);
  706.     }
  707.     }
  708.  
  709.     for (i=0; i<volCnt; i++) {
  710.     if (slot == volList[i].location) {
  711.         return volList[i].volId;
  712.     }
  713.     }
  714.     return -1;
  715. }
  716.  
  717.  
  718.  
  719. /*
  720.  *----------------------------------------------------------------------
  721.  *
  722.  * FindDeviceInList --
  723.  *
  724.  *    Locate device name in list.
  725.  *
  726.  * Results:
  727.  *    none.
  728.  *
  729.  * Side effects:
  730.  *    none.
  731.  *
  732.  *----------------------------------------------------------------------
  733.  */
  734.  
  735. static int
  736. FindDeviceInList(reader)
  737.     char *reader;             /* name of device */
  738. {
  739.     int i;
  740.  
  741.     /* Must inquire, if we don't have a devconfig file */
  742.     if (devCnt == 0) {
  743.     sprintf(printBuf, "What slot does device % use? [<return> to exit] ",
  744.         reader);
  745.     return Utils_GetInteger(printBuf, 0, INT_MAX);
  746.     }
  747.  
  748.     for (i=0; i<devCnt; i++) {
  749.     if (strcmp(reader,devList[i].name) == 0) {
  750.         return devList[i].location;
  751.     }
  752.     }
  753.     return -1;
  754. }
  755.  
  756.  
  757.  
  758. /*
  759.  *----------------------------------------------------------------------
  760.  *
  761.  * CheckOptions -- 
  762.  *
  763.  *    Make sure command line options look reasonable
  764.  *
  765.  * Results:
  766.  *    none.
  767.  *
  768.  * Side effects:
  769.  *    none.
  770.  *
  771.  *----------------------------------------------------------------------
  772.  */
  773.  
  774. static void
  775. CheckOptions(parmsPtr, cmdPtr)
  776.     Parms *parmsPtr;          /* parameter block */
  777.     int *cmdPtr;              /* converted command */
  778. {
  779.     Cmd *localCmdPtr;
  780.  
  781.     if ((localCmdPtr=FindCmdInList(parmsPtr->cmd)) == NULL) {
  782.     Utils_Bailout("Need argument for -cmd: insert, remove, load, unload,\nmove, readlabel, listvols, msg, or opendoor.\n", BAIL_PRINT);
  783.     }
  784.     if ((localCmdPtr->flags & NEEDVOL) &&
  785.     ((parmsPtr->volId == DEF_VOL) || (parmsPtr->volId < 0))) {
  786.     Utils_Bailout("Need non-negative argument on -vol option.\n",
  787.               BAIL_PRINT);
  788.     }
  789.     if ((localCmdPtr->flags & NEEDSLOT) &&
  790.     ((parmsPtr->slot == DEF_SLOT) || (parmsPtr->slot < 0))) {
  791.     Utils_Bailout("Need non-negative argument on -slot option.\n",
  792.               BAIL_PRINT);
  793.     }
  794.     if ((localCmdPtr->flags & NEEDSLOT2) &&
  795.     ((parmsPtr->slot == DEF_SLOT2) || (parmsPtr->slot2 < 0))) {
  796.     Utils_Bailout("Need non-negative argument on -slot2 option.\n",
  797.               BAIL_PRINT);
  798.     }
  799.     if ((localCmdPtr->flags & NEEDDEV) &&
  800.     (strcmp(parmsPtr->dev, DEF_DEV) == 0)) {
  801.     Utils_Bailout("Need non-null device name.\n", BAIL_PRINT);
  802.     }
  803.     *cmdPtr = localCmdPtr->id;
  804. }
  805.  
  806.  
  807.  
  808. /*
  809.  *----------------------------------------------------------------------
  810.  *
  811.  * FindCmdInList --
  812.  *
  813.  *    Locate user command and return entry.
  814.  *
  815.  * Results:
  816.  *    none.
  817.  *
  818.  * Side effects:
  819.  *    none.
  820.  *
  821.  *----------------------------------------------------------------------
  822.  */
  823.  
  824. static Cmd *
  825. FindCmdInList(string)
  826.     char *string;             /* Command string */
  827. {
  828.     int i;
  829.     static Cmd cmds[NUMCMDS] = {
  830.     {"insert",   CMD_INSERT,     NEEDVOL+NEEDSLOT},
  831.     {"remove",   CMD_REMOVE,     NEEDVOL},
  832.     {"load",     CMD_LOAD,       NEEDVOL+NEEDDEV},
  833.     {"unload",   CMD_UNLOAD,     NEEDVOL+NEEDDEV},
  834.     {"opendoor", CMD_OPENDOOR,   0},
  835.     {"msg",      CMD_DISPMSG,    0},
  836.     {"move",     CMD_MOVE,       NEEDSLOT+NEEDSLOT2},
  837.     {"readlabel", CMD_READLABEL, NEEDSLOT},
  838.     {"listvols", CMD_LISTVOLS,   0}
  839.     };
  840.  
  841.     for (i=0; i<NUMCMDS; i++) {
  842.     if (strcmp(string,cmds[i].name) == 0) {
  843.         return &cmds[i];
  844.     }
  845.     }
  846.  
  847.     return NULL;
  848. }
  849.  
  850.  
  851. /*
  852.  *----------------------------------------------------------------------
  853.  *
  854.  * PruneDirectory --
  855.  *
  856.  *    Locate and remove all references to specified volume
  857.  *
  858.  * Results:
  859.  *    none.
  860.  *
  861.  * Side effects:
  862.  *    none.
  863.  *
  864.  *----------------------------------------------------------------------
  865.  */
  866.  
  867. static int
  868. PruneDirectory(minTBuf, maxTBuf, dirPath, curPath)
  869.     int minTBuf;              /* lowest tbuf on volume */
  870.     int maxTBuf;              /* highest tbuf on volume */
  871.     char *dirPath;            /* directory to be pruned */
  872.     char *curPath;            /* current user path */
  873. {
  874.     T_FileStat statInfo;
  875.     char indxPath[2*T_MAXPATHLEN];
  876.     char newPath[2*T_MAXPATHLEN];
  877.     char filePath[2*T_MAXPATHLEN];
  878.     DIR *dirPtr;
  879.     DirObject *entryPtr;
  880.     struct stat unixStatBuf;
  881.     FILE *indxStream;
  882.     FILE *newStream;
  883.     int pruneCnt = 0;
  884.     char *simpleName;
  885.  
  886.     /*
  887.      * First prune the file in this directory
  888.      */
  889.     strcpy(indxPath, dirPath);
  890.     strcat(indxPath, "/_jaquith.files");
  891.     strcpy(newPath, dirPath);
  892.     strcat(newPath, "/_jaquith.files.new");
  893.     if ((indxStream=fopen(indxPath, "r")) == (FILE *)NULL) {
  894.     sprintf(printBuf, "open %s", indxPath);
  895.     perror(printBuf);
  896.     } else if ((newStream=fopen(newPath, "w")) == (FILE *)NULL) {
  897.     sprintf(printBuf, "open %s", newPath);
  898.     perror(printBuf);
  899.     } else {
  900.     while (Indx_ReadIndxEntry(indxStream, &statInfo) == T_SUCCESS) {
  901.         if ((statInfo.tBufId >= minTBuf) &&
  902.         (statInfo.tBufId <= maxTBuf)) {
  903.         pruneCnt++;
  904.         } else {
  905.         simpleName = statInfo.fileName;
  906.         if (*curPath == '\0') {
  907.             statInfo.fileName = Str_Dup("/");
  908.         } else {
  909.             statInfo.fileName = Str_Cat(3, curPath, "/", simpleName);
  910.         }
  911.         Indx_WriteIndxEntry(&statInfo, -1, newStream);
  912.         MEM_FREE("PruneDirectory", simpleName);
  913.         Utils_FreeFileStat(&statInfo, 0);
  914.         }
  915.     }    
  916.     fclose(indxStream);
  917.     fclose(newStream);
  918.     if (unlink(indxPath) == -1) {
  919.         sprintf(printBuf, "unlink %s", indxPath);
  920.         perror(printBuf);
  921.     } else if (rename(newPath, indxPath) == -1) {
  922.         sprintf(printBuf, "rename %s to %s", newPath, indxPath);
  923.         perror(printBuf);
  924.     }
  925.     }
  926.  
  927.     /*
  928.      * Now recurse through child directories
  929.      */
  930.     if ((dirPtr=(DIR *)opendir(dirPath)) == (DIR *) NULL) {
  931.     sprintf(printBuf, "open dir %s", dirPath);
  932.     perror(printBuf);
  933.     } else {
  934.     while ((entryPtr=readdir(dirPtr)) != (DirObject *)NULL) {
  935.         if ((strcmp(entryPtr->d_name, ".") != 0) &&
  936.         (strcmp(entryPtr->d_name, "..") != 0)) {
  937.         strcpy(indxPath, dirPath);
  938.         strcat(indxPath, "/");
  939.         strcat(indxPath, entryPtr->d_name);
  940.         if (stat(indxPath, &unixStatBuf) == -1) {
  941.             sprintf(printBuf, "stat %s", indxPath);
  942.             perror(printBuf);
  943.         } else if (S_ISADIR(unixStatBuf.st_mode)) {
  944.             strcpy(newPath, curPath);
  945.             strcat(newPath, "/");
  946.             if (*curPath != '\0') {
  947.             strcat(newPath, entryPtr->d_name);
  948.             }
  949.             pruneCnt += PruneDirectory(minTBuf, maxTBuf,
  950.                            indxPath, newPath);
  951.         }
  952.         }
  953.     }
  954.     closedir(dirPtr);
  955.     }
  956.  
  957.     return pruneCnt;
  958. }
  959.